package com.ing5.BL.android.cinece.api.client;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.util.Log;

public abstract class AbstractRequest<T> {
	String uri;

	protected AbstractCache cache = null;
	protected HashMap<String, String> cacheDictionnary;

	public void setCacheManager(AbstractCache cache) {
		this.cache = cache;
		cacheDictionnary = cache.LoadDictionnary();
	}

	protected abstract Class<T> getResultType();

	public String sendRequest(DefaultHttpClient client) {

		HttpGet getRequest = new HttpGet(uri);
		String result = "";

		try {

			// --- Execute the request
			HttpResponse getResponse = client.execute(getRequest);

			final int statusCode = getResponse.getStatusLine().getStatusCode();

			// ---- If status code is NOT 200 (ie is KO)
			if (statusCode != HttpStatus.SC_OK) {
				Log.w("DataLoader", "Error " + statusCode + " for URL " + uri);
			}

			// ------- Return the content => JSON in a String
			String line = null;
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					getResponse.getEntity().getContent()));
			while (null != (line = reader.readLine())) {
				result += line;
			}

			if (cache != null) {
				Date fileDate = new Date();
				String fileName = UUID.randomUUID().toString() + "_"
						+ new SimpleDateFormat("yyyy-MM-dd").format(fileDate)
						+ ".tmp";
				if (cacheDictionnary.get(uri) != null) {
					cacheDictionnary.remove(uri);
				}

				cacheDictionnary.put(uri, fileName);
				cache.WriteCache(fileName, result);
				cache.SaveDictionnary(cacheDictionnary);
			}

		} catch (Exception e) {
			getRequest.abort();
			result = null;
		}
		return result;
	}

	public T execute(DefaultHttpClient client) {

		String result = "";
		T object = null;

		// ------------------- if the cache system is enable
		if (cache != null && cacheDictionnary.get(uri) != null) {

			result = cache.ReadCache(cacheDictionnary.get(uri));

			// send the request in a thread to update the cache
			Thread requestThread = new RequestThread(this, client, "request");
			requestThread.start();

		} // ------------------- Cache system not enable -> send a request
		else {
			result = sendRequest(client);
		}

		/******************************
		 ** Deserialize
		 ******************************/
		try {
			object = new JsonParser().parseJson(result, getResultType());
		} catch (Exception e) {
			// fail to deserialized
			Log.i("DEBUG", "Failed to deserialize - " + e);
			if (cache != null)
				cache.clearCache();
		}
		
		return object;
	}
}
